import {CardInfo, CardType} from "./GridsLib";
import ResLoader from "../../Core/Libs/ResLoader";

const {ccclass, property} = cc._decorator;

@ccclass
export default class CardLib extends cc.Component {

    @property(cc.Node)
    cardBack: cc.Node = null;

    @property(cc.Node)
    cardFront: cc.Node = null;

    @property(cc.Node)
    attack: cc.Node = null;

    @property(cc.Node)
    recover: cc.Node = null;

    @property(cc.Node)
    defense: cc.Node = null;

    @property(cc.Node)
    skill: cc.Node = null;

    @property(cc.Node)
    normal: cc.Node = null;

    @property(cc.Node)
    container: cc.Node = null;



    private cardInfo: CardInfo;

    //卡牌数值
    _hp: number = 0;
    _maxHp: number = 0;


    //额外的护盾
    _defenseValue: number = 0;

    public init(w:number,h:number){
        this.node.width = w;
        this.node.height = h;

        this.cardFront.width = w;
        this.cardFront.height = h;

        this.cardBack.width = w;
        this.cardBack.height = h;

        this.reset()
    }

    public get hp(): number {
        if (this.cardInfo.type != CardType.Hero) {
            return 0;
        }

        return this._hp + this._defenseValue;
    }

    public addHp(n: number) {
        if (this.cardInfo.type != CardType.Hero) {
            return;
        }

        //扣血
        if (n < 0) {
            let subHp = Math.abs(n);

            //先减去护盾值，如果能抵消 那么直接返回
            if( this._defenseValue > 0){
                //护盾能抵扣
                if (this._defenseValue >= subHp ) {
                    this.addDefenseValue(-subHp);
                    return;
                }

                //不能全部抵扣 计算差值 再扣血
                n = this._defenseValue - subHp;
                this.addDefenseValue(-subHp);
            }
        }

        this._hp += n;
        this._hp = this._hp >= this._maxHp ? this._maxHp : this._hp;


        this.attack.getChildByName("value").getComponent(cc.Label).string = this._hp + "/" + this._maxHp;
        this.attack.active = true;
    }


    public addMaxHp(n: number) {
        if (!n) {
            return;
        }

        if (this.cardInfo.type != CardType.Hero && this.cardInfo.type != CardType.Boss) {
            return;
        }

        this._maxHp = n;
        this.attack.getChildByName("value").getComponent(cc.Label).string = this._hp + "/" + this._maxHp;
        this.attack.active = true;
    }

    //非英雄卡设置值
    public addValue(n:number){
        let parentNode: cc.Node;
        switch (this.cardInfo.type) {
            case CardType.Hero:
            case CardType.Trap:
            case CardType.Boss:
            case CardType.Monster:
                parentNode = this.attack;
                break;
            case CardType.Health:
                parentNode = this.recover;
                break;
            case CardType.Shield:
                parentNode = this.defense;
                break;
            case CardType.Treasure:
            case CardType.Coin:
                parentNode = this.normal;
                break
            case CardType.Skill:
                parentNode = this.skill
        }

        parentNode.getChildByName("value").getComponent(cc.Label).string = (this.cardInfo.value + n).toString();
    }


    public get defenseValue() {
        return this._defenseValue;
    }

    public addDefenseValue(n: number) {
        if (this.cardInfo.type != CardType.Hero) {
            return;
        }

        this._defenseValue += n;
        if (this._defenseValue > 0) {
            this.defense.getChildByName("value").getComponent(cc.Label).string = this._defenseValue.toString();
            this.defense.active = true;
        } else {
            this._defenseValue = 0;
            this.defense.active = false;
        }
    }

    public async setCardAttr(cardInfo: CardInfo) {

        if (this.cardInfo) {
            this.reset();
        }

        this.cardInfo = cardInfo;

        //设置背景
        await this.setCardBackground();

        //设置角色
        await this.setCardRole();

        //设置
        await this.setCardLabel();
    }

    public reset() {
        this.attack.active = false;
        this.recover.active = false;
        this.defense.active = false;
        this.skill.active = false;
        this.normal.active = false;

        this.cardBack.active = true;

        this.cardFront.active = false;
        this.cardFront.getComponent(cc.Sprite).spriteFrame = null;


        //卡牌数值
        this._hp = 0;
        this._maxHp= 0;

        //额外的护盾
        this._defenseValue= 0;
    }


    public async setCardBackground() {
        let assetPath = "texture/";
        switch (this.cardInfo.type) {
            case CardType.Hero:
                assetPath += "card-bg-2"
                break;
            case CardType.Trap:
            case CardType.Boss:
            case CardType.Monster:
                assetPath += "card-bg-4"
                break;
            default:
                assetPath += "card-bg-3"
        }

        this.cardFront.getComponent(cc.Sprite).spriteFrame = await ResLoader.load(assetPath, cc.SpriteFrame)
    }


    public async setCardRole() {
        let assetPrefix = cc.Enum(CardType)[this.cardInfo.type].toLowerCase()
        this.container.getChildByName("role").getComponent(cc.Sprite).spriteFrame =
            await ResLoader.load("texture/" + assetPrefix + "-" + this.cardInfo.id, cc.SpriteFrame)
        this.container.active = true;
    }

    public async setCardLabel() {

        //英雄卡才有 最大值
        if (this.cardInfo.maxValue) {
            this._maxHp = this.cardInfo.maxValue;
            this.addHp(this.cardInfo.value);
            return;
        }

        let parentNode: cc.Node;
        switch (this.cardInfo.type) {
            case CardType.Hero:
            case CardType.Trap:
            case CardType.Boss:
            case CardType.Monster:
                parentNode = this.attack;
                break;
            case CardType.Health:
                parentNode = this.recover;
                break;
            case CardType.Shield:
                parentNode = this.defense;
                break;
            case CardType.Treasure:
            case CardType.Coin:
                parentNode = this.normal;
                break
            case CardType.Skill:
                parentNode = this.skill
        }


        parentNode.getChildByName("value").getComponent(cc.Label).string = this.cardInfo.value.toString();
        parentNode.active = true;
    }

    // update (dt) {}
}
